package com.itheima.Wuziqi.ui;

import com.itheima.Wuziqi.service.GameRule;
import com.itheima.Wuziqi.dao.UserDatabase;
import com.itheima.Wuziqi.entity.User;
import com.itheima.Wuziqi.entity.AIPlayer;
import com.itheima.Wuziqi.entity.HumanPlayer;
import com.itheima.Wuziqi.entity.Player;


import java.awt.Point;
import java.util.ArrayList;
import java.util.List;


/**
 * 游戏控制器，协调游戏流程
 */
public class GameController {
    private Board board;
    private GameRule rule;
    private Player currentPlayer;
    private Player player1;
    private Player player2;
    private boolean gameOver;
    private List<GameListener> listeners = new ArrayList<>();
    private User currentUser;
    private UserDatabase userDatabase;
    
    public GameController(Board board, GameRule rule, UserDatabase userDatabase) {
        this.board = board;
        this.rule = rule;
        this.gameOver = false;
        this.userDatabase = userDatabase;
    }

    // 设置玩家
    public void setPlayers(Player p1, Player p2) {
        this.player1 = p1;
        this.player2 = p2;
        // 设置当前玩家为player1（黑棋先行）
        this.currentPlayer = p1;
    }

    // 开始新游戏
    public void startNewGame() {
        // 检查玩家是否已经设置
        if (player1 == null || player2 == null) {
            System.err.println("Error: Players not set before starting game");
            return;
        }

        board.reset();
        gameOver = false;
        currentPlayer = player1; // 黑棋先行
        notifyGameStarted();
    }
    
    // 处理玩家落子
    public boolean makeMove(Point point) {
        if (gameOver) return false;

        // 添加对 currentPlayer 的空值检查
        if (currentPlayer == null) {
            System.err.println("Error: currentPlayer is null. Game may not be started.");
            return false;
        }

        // 如果是人类玩家，设置其落子位置
        if (currentPlayer instanceof HumanPlayer) {
            ((HumanPlayer) currentPlayer).setMove(point);
        }
        
        // 获取玩家的落子位置
        Point move = currentPlayer.makeMove(board, rule);
        if (move == null) return false;
        
        int row = move.y;
        int col = move.x;
        
        // 检查落子是否有效
        if (!rule.isValidMove(board.getBoardState(), row, col)) {
            return false;
        }
        
        // 放置棋子
        board.placePiece(row, col, currentPlayer.getType());
        
        // 通知落子事件
        notifyPiecePlaced(row, col, currentPlayer.getType());
        
        // 检查是否获胜
        if (rule.checkWin(board.getBoardState(), row, col, currentPlayer.getType())) {
            gameOver = true;
            notifyGameWon(currentPlayer);
            
            // 更新用户统计信息
            updateUserStats(currentPlayer, true);
            return true;
        }
        
        // 检查是否平局
        if (rule.checkDraw(board.getBoardState())) {
            gameOver = true;
            notifyGameDrawn();
            
            // 更新用户统计信息
            updateUserStats(null, false);
            return true;
        }
        
        // 切换玩家
        currentPlayer = (currentPlayer == player1) ? player2 : player1;
        notifyPlayerChanged(currentPlayer);
        
        // 如果下一个玩家是AI，自动落子
        if (currentPlayer instanceof AIPlayer && !gameOver) {
            new Thread(() -> {
                try {
                    Thread.sleep(500); // 短暂延迟，让玩家看清
                    makeMove(null);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        
        return true;
    }

    // 更新用户统计信息
    private void updateUserStats(Player winner, boolean isWin) {
        if (currentUser == null || userDatabase == null) return;

        // 如果是平局
        if (winner == null) {
            currentUser.incrementDraw();
            userDatabase.update(currentUser);
            return;
        }

        // 检查当前用户是否参与了游戏
        boolean isCurrentUserPlayer1 = (player1 instanceof HumanPlayer) &&
                ((HumanPlayer) player1).getName().equals(currentUser.getUsername());
        boolean isCurrentUserPlayer2 = (player2 instanceof HumanPlayer) &&
                ((HumanPlayer) player2).getName().equals(currentUser.getUsername());

        // 如果当前用户没有参与游戏，则不更新统计
        if (!isCurrentUserPlayer1 && !isCurrentUserPlayer2) {
            return;
        }

        // 如果当前用户获胜
        if (winner instanceof HumanPlayer && ((HumanPlayer) winner).getName().equals(currentUser.getUsername())) {
            currentUser.incrementWin();
        }
        // 如果当前用户失败
        else {
            currentUser.incrementLose();
        }

        userDatabase.update(currentUser);
    }
    
    // 添加游戏监听器
    public void addGameListener(GameListener listener) {
        listeners.add(listener);
    }
    
    // 移除游戏监听器
    public void removeGameListener(GameListener listener) {
        listeners.remove(listener);
    }
    
    // 通知游戏开始
    private void notifyGameStarted() {
        for (GameListener listener : listeners) {
            listener.gameStarted();
        }
    }
    
    // 通知棋子已放置
    private void notifyPiecePlaced(int row, int col, int playerType) {
        for (GameListener listener : listeners) {
            listener.piecePlaced(row, col, playerType);
        }
    }
    
    // 通知游戏获胜
    private void notifyGameWon(Player winner) {
        for (GameListener listener : listeners) {
            listener.gameWon(winner);
        }
    }
    
    // 通知游戏平局
    private void notifyGameDrawn() {
        for (GameListener listener : listeners) {
            listener.gameDrawn();
        }
    }
    
    // 通知玩家切换
    private void notifyPlayerChanged(Player newPlayer) {
        for (GameListener listener : listeners) {
            listener.playerChanged(newPlayer);
        }
    }
    
    // getter方法
    public Board getBoard() {
        return board;
    }
    
    public Player getCurrentPlayer() {
        return currentPlayer;
    }
    
    public boolean isGameOver() {
        return gameOver;
    }
    
    public void setCurrentUser(User user) {
        this.currentUser = user;
    }
    
    public User getCurrentUser() {
        return currentUser;
    }
}
    